#include <iostream>
#include "../libfractal/fvector.hpp"
#include "../libfractal/lsystem.hpp"
#include "../libfractal/fvertexarray.hpp"
#include "../libfractal/fdynamicarray.hpp"


using namespace std;


void test_fvector(void)
{
    cout << endl << "Testing FVector2d" << endl;
    FVector2d<double> v1, v2(1.05, 2.99);
    cout << "Default constructor: (x: " << v1.x << "; y: " << v1.y << ")" 
	 << endl;
    cout << "Constructor: " << v2.x << " " << v2.y << endl;
    FVector2d<double> v3(v2);
    cout << "Copy constructor: " << v3.x << " " << v3.y << endl;
    v1 = v2;
    cout << "operator=: " << v1.x << " " << v1.y << endl;
}


/*void test_lsysrule(void)
{
    cout << endl << "Testing LSysRule" << endl;
    string s("FFF-[F+F]");
    LSysRule r1, r2('F', string("F+F-[FF]")), r3('F', s);
    cout << "Default constructor: (from: " << r1.from << "; to: " << r1.to 
	 << ")" << endl;
    cout << "Constructor const char*: (from: " <<  r2.from << "; to: " << r2.to 
	 << ")" << endl;
    cout << "Constructor const string&: (from: " << r3.from << "; to: " 
	 << r3.to << ")" << endl;
    LSysRule r4 = r3;
    cout << "Copy constructor: (from: " << r4.from << "; to: " << r4.to 
	 << ")" << endl;
    r2 = r3;
    cout << "operator=: (from: " << r2.from << "; to: " << r2.to 
	 << ")" << endl;
} */


template<class VectorType>
void print_va(FVertexArray<VectorType> &va)
{
    for (int i = 0; i < va.size(); i++)
	cout << i << ": (" << va[VectorType::dim*i] << "; " << va[VectorType::dim*i+1] << ")" << endl;
}


void test_vertexarr(void)
{
    cout << endl << "Testing FVertexArray" << endl;
    FVertexArray<FVector2d<double> > v1, v2(10, 2.0);
    cout << "Default constructor:" << endl;
    print_va(v1);
    cout << "Constructor (size, val):" << endl;
    print_va(v2);
    v1 = v2;
    cout << "operator=" << endl;
    print_va(v1);
    v1[5] = 100.53;
    cout << "operator[]" << endl;
    print_va(v1);
    cout << "v1.size: " << v1.size() << " v1.capacity: " << v1.capacity() << endl;
    v1.push_back(FVector2d<double>(123.321, 123.321));
    cout << "v1.size: " << v1.size() << " v1.capacity: " << v1.capacity() << endl;
    print_va(v1);
    v1.resize(0);
    cout << "v1.size: " << v1.size() << " v1.capacity: " << v1.capacity() << endl;
    print_va(v1);
    v1.reserve(100);
    for (int i = 0; i < 110; i++) {
	v1.push_back(FVector2d<double>(i,i));
	cout << "v1.size: " << v1.size() << " v1.capacity: " << v1.capacity() << endl;
    }
    print_va(v1);
}


void test_lsys(void)
{
    cout << endl << "Testing LSystemDescr" << endl;
    string axiom = "F";
    vector<LSysRule> r(1);
    r[0] = LSysRule('F', "FF+F+F");
    LSystem d(0, 1.0, 22.5, axiom, r);
    FVertexArray<FVector2d<double> > va;
/*    cout << "gen str age " << d.age << ": " << d.render(va) << endl;
    d.age = 1;
    cout << "gen str age " << d.age << ": " << d.render(va) << endl;
    d.age = 2;
    cout << "gen str age " << d.age << ": " << d.render(va) << endl;*/
}


void test_fdynarr(void)
{
    cout << endl << "Testing FDynamicArray" << endl;
    FDynamicArray<FVector2d<double> > da(5, FVector2d<double>(3.14, 15.92));
    for (int i = 0; i < da.size(); i++)
	cout << i << ". (" << da[i].x << "; " << da[i].y << ")" << endl;
    FDynamicArray<FVector2d<double> > db = da;
    for (int i = 0; i < da.size(); i++)
	cout << i << ". (" << db[i].x << "; " << db[i].y << ")" << endl;
    da.push_back(FVector2d<double>(100, 1));
    for (int i = 0; i < da.size(); i++)
	cout << i << ". (" << da[i].x << "; " << da[i].y << ")" << endl;
    da.resize(50, FVector2d<double>(7, 7));
    for (int i = 0; i < da.size(); i++)
	cout << i << ". (" << da[i].x << "; " << da[i].y << ")" << endl;
}


int main(int argc, char *argv[])
{
    test_fvector();
/*    test_lsysrule();*/	
      test_vertexarr();
/*    test_lsys();
    test_fdynarr();*/
    return 0;
}
